import { ElMessage } from 'element-plus'

// 基础配置
const BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8081/api'

/**
 * 通用请求配置
 */
const defaultConfig = {
  headers: {
    'Content-Type': 'application/json',
  },
  timeout: 10000, // 10秒超时
}

/**
 * 处理响应数据
 * @param {Response} response - fetch响应对象
 * @returns {Promise} 解析后的数据
 */
const handleResponse = async (response) => {
  if (!response.ok) {
    throw new Error(`HTTP错误: ${response.status} ${response.statusText}`)
  }
  
  const contentType = response.headers.get('content-type')
  if (contentType && contentType.includes('application/json')) {
    return await response.json()
  } else {
    return await response.text()
  }
}

/**
 * 处理业务逻辑错误
 * @param {Object} data - 服务器返回的数据
 * @returns {Object} 处理后的数据
 */
const handleBusinessError = (data) => {
  if (data.success === 1) {
    // 业务逻辑错误
    const errorMessage = data.err || '操作失败'
    ElMessage.error(errorMessage)
    throw new Error(errorMessage)
  }
  return data
}

/**
 * 处理网络错误
 * @param {Error} error - 错误对象
 */
const handleNetworkError = (error) => {
  console.error('API请求错误:', error)
  let errorMessage = '网络请求失败'
  
  if (error.name === 'TypeError' && error.message.includes('fetch')) {
    errorMessage = '网络连接失败，请检查网络设置'
  } else if (error.message.includes('timeout')) {
    errorMessage = '请求超时，请稍后重试'
  } else if (error.message.includes('HTTP错误')) {
    errorMessage = error.message
  } else {
    errorMessage = error.message || '未知错误'
  }
  
  ElMessage.error(errorMessage)
  throw error
}

/**
 * 构建GET请求的URL参数
 * @param {Object} params - 参数对象
 * @returns {string} 查询字符串
 */
const buildQueryString = (params) => {
  if (!params || typeof params !== 'object') {
    return ''
  }
  
  const queryParams = new URLSearchParams()
  Object.keys(params).forEach(key => {
    if (params[key] !== undefined && params[key] !== null) {
      queryParams.append(key, params[key])
    }
  })
  
  const queryString = queryParams.toString()
  return queryString ? `?${queryString}` : ''
}

/**
 * 通用GET请求
 * @param {string} url - 请求路径
 * @param {Object} params - 查询参数
 * @param {Object} config - 请求配置
 * @returns {Promise} 请求结果
 */
export const get = async (url, params = {}, config = {}) => {
  try {
    const queryString = buildQueryString(params)
    const fullUrl = `${BASE_URL}${url}${queryString}`
    
    const response = await fetch(fullUrl, {
      method: 'GET',
      ...defaultConfig,
      ...config,
    })
    
    const data = await handleResponse(response)
    return handleBusinessError(data)
  } catch (error) {
    handleNetworkError(error)
  }
}

/**
 * 通用POST请求
 * @param {string} url - 请求路径
 * @param {Object} data - 请求数据
 * @param {Object} config - 请求配置
 * @returns {Promise} 请求结果
 */
export const post = async (url, data = {}, config = {}) => {
  try {
    const fullUrl = `${BASE_URL}${url}`
    // console.log(data)
    
    const response = await fetch(fullUrl, {
      method: 'POST',
      body: JSON.stringify(data),
      ...defaultConfig,
      ...config,
    })
    
    const responseData = await handleResponse(response)
    return handleBusinessError(responseData)
  } catch (error) {
    handleNetworkError(error)
  }
}

/**
 * 文件上传POST请求
 * @param {string} url - 请求路径
 * @param {FormData} formData - 表单数据
 * @param {Object} config - 请求配置
 * @returns {Promise} 请求结果
 */
export const postFile = async (url, formData, config = {}) => {
  try {
    const fullUrl = `${BASE_URL}${url}`
    
    const response = await fetch(fullUrl, {
      method: 'POST',
      body: formData, // 直接使用FormData，不进行JSON.stringify
      headers: {
        // 不设置Content-Type，让浏览器自动设置multipart/form-data
        ...config.headers
      },
      ...config,
    })
    
    const responseData = await handleResponse(response)
    return handleBusinessError(responseData)
  } catch (error) {
    handleNetworkError(error)
  }
}

/**
 * 通用PUT请求
 * @param {string} url - 请求路径
 * @param {Object} data - 请求数据
 * @param {Object} config - 请求配置
 * @returns {Promise} 请求结果
 */
export const put = async (url, data = {}, config = {}) => {
  try {
    const fullUrl = `${BASE_URL}${url}`
    
    const response = await fetch(fullUrl, {
      method: 'PUT',
      body: JSON.stringify(data),
      ...defaultConfig,
      ...config,
    })
    
    const responseData = await handleResponse(response)
    return handleBusinessError(responseData)
  } catch (error) {
    handleNetworkError(error)
  }
}

/**
 * 通用DELETE请求
 * @param {string} url - 请求路径
 * @param {Object} params - 查询参数
 * @param {Object} config - 请求配置
 * @returns {Promise} 请求结果
 */
export const del = async (url, params = {}, config = {}) => {
  try {
    const queryString = buildQueryString(params)
    const fullUrl = `${BASE_URL}${url}${queryString}`
    
    const response = await fetch(fullUrl, {
      method: 'DELETE',
      ...defaultConfig,
      ...config,
    })
    
    const data = await handleResponse(response)
    return handleBusinessError(data)
  } catch (error) {
    handleNetworkError(error)
  }
}

/**
 * 设置请求头
 * @param {string} key - 头部键名
 * @param {string} value - 头部值
 */
export const setHeader = (key, value) => {
  defaultConfig.headers[key] = value
}

/**
 * 设置认证token
 * @param {string} token - 认证token
 */
export const setAuthToken = (token) => {
  if (token) {
    defaultConfig.headers['Authorization'] = `Bearer ${token}`
  } else {
    delete defaultConfig.headers['Authorization']
  }
}

/**
 * 分页查询参数构建器
 * @param {Object} options - 分页选项
 * @param {number} options.currentPage - 当前页码，默认为1
 * @param {number} options.size - 每页数量，默认为10
 * @param {Object} options.otherParams - 其他查询参数
 * @returns {Object} 完整的分页查询参数
 */
export const buildPaginationParams = (options = {}) => {
  const {
    currentPage = 1,
    size = 10,
    otherParams = {}
  } = options

  return {
    currentPage: Math.max(1, currentPage),
    size: Math.max(1, size),
    ...otherParams
  }
}

/**
 * 分页响应数据处理器
 * @param {Object} response - 服务器响应数据
 * @param {Object} requestParams - 请求参数
 * @returns {Object} 处理后的分页数据
 */
export const handlePaginationResponse = (response, requestParams = {}) => {
  if (!response || !response.data) {
    return {
      list: [],
      pagination: {
        currentPage: requestParams.currentPage || 1,
        size: requestParams.size || 10,
        total: 0,
        pages: 0
      }
    }
  }

  const { currentPage = 1, size = 10 } = requestParams
  const list = response.data.data
  const total = response.data.total

  return {
    list,
    pagination: {
      currentPage,
      size,
      total,
      pages: Math.ceil(total / size)
    }
  }
}

/**
 * 分页查询GET请求
 * @param {string} url - 请求路径
 * @param {Object} options - 分页选项
 * @param {number} options.currentPage - 当前页码
 * @param {number} options.size - 每页数量
 * @param {Object} options.otherParams - 其他查询参数
 * @param {Object} config - 请求配置
 * @returns {Promise} 分页查询结果
 */
export const getWithPagination = async (url, options = {}, config = {}) => {
  try {
    const params = buildPaginationParams(options)
    const response = await get(url, params, config)
    // console.log(response)
    return handlePaginationResponse(response, params)
  } catch (error) {
    // 错误已经被get方法处理，这里重新抛出
    throw error
  }
}

/**
 * 分页查询POST请求
 * @param {string} url - 请求路径
 * @param {Object} options - 分页选项
 * @param {number} options.currentPage - 当前页码
 * @param {number} options.size - 每页数量
 * @param {Object} options.otherParams - 其他查询参数
 * @param {Object} config - 请求配置
 * @returns {Promise} 分页查询结果
 */
export const postWithPagination = async (url, options = {}, config = {}) => {
  try {
    const params = buildPaginationParams(options)
    const response = await post(url, params, config)
    return handlePaginationResponse(response, params)
  } catch (error) {
    // 错误已经被post方法处理，这里重新抛出
    throw error
  }
}

/**
 * 获取当前请求配置
 * @returns {Object} 当前配置
 */
export const getConfig = () => {
  return { ...defaultConfig }
}

export default {
  get,
  post,
  put,
  del,
  getWithPagination,
  postWithPagination,
  buildPaginationParams,
  handlePaginationResponse,
  setHeader,
  setAuthToken,
  getConfig,
} 